/**
  需求：实现长按，用户需要按下并按住按钮几秒钟，触发相应的事件

  思路：
    创建一个计时器， 2 秒后执行函数
    当用户按下按钮时触发 mousedown 事件，启动计时器；用户松开按钮时调用 mouseup 事件。
    如果 mouseup 事件 2 秒内被触发，就清除计时器，当作一个普通的点击事件
    如果计时器没有在 2 秒内清除，则判定为一次长按，可以执行关联的函数。
    在移动端要考虑 touchstart，touchend 事件
 */
import { ObjectDirective } from 'vue';

const longpress: ObjectDirective<any, Function> = {
  created(el, binding) {
    const { value } = binding;
    if (typeof value !== 'function') {
      if (typeof value === 'undefined' && process.env.NODE_ENV !== 'production') {
       console.warn('[directives of longpress]: 你是否没有在setup中返回binding.value所需要的函数?')
      }
      throw 'callback must be a function';
    }

    // 运行函数
    el.handler = (e: any) => {
      value(e)
    };
    // 定义变量(接收setTimeout返回值)
    el.pressTimer = null;
    // 创建计时器（ 2秒后执行函数 ）
    el.start = (e: any) => {
      // 移动端兼容
      if (e.type === 'click' && e.button !== 0) {
        return
      }
      if (el.pressTimer === null) {
        el.pressTimer = setTimeout(() => {
          el.handler(e)
        }, 2000);
      }
    }
    // 取消计时器
    el.cancel = (e:any) => {
      // console.log('cancal',e)
      if (el.pressTimer !== null) {
        clearTimeout(el.pressTimer)
        el.pressTimer = null
      }
    }

    // 添加事件监听器
    el.addEventListener('mousedown', el.start)
    el.addEventListener('touchstart', el.start)
    // 取消计时器
    el.addEventListener('click', el.cancel)
    el.addEventListener('mouseup', el.cancel)
    el.addEventListener('touchend', el.cancel)
    el.addEventListener('touchcancel', el.cancel)
  },
  updated(el, { value }) {
    el.handler = (e: any) => {
      value(e)
    };
  },
  beforeUnmount(el) {
    el.removeEventListener('mousedown', el.start)
    el.removeEventListener('touchstart', el.start)
    el.removeEventListener('click', el.cancel)
    el.removeEventListener('mouseup', el.cancel)
    el.removeEventListener('touchend', el.cancel)
    el.removeEventListener('touchcancel', el.cancel)
    el.start = null;
    el.cancel = null;
    el.pressTimer = null;
    el.handler = null;
  }
}

export default longpress;
